<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\common\command;

use app\common\enum\DrawEnum;
use app\common\model\draw\DrawTask;
use app\common\service\discord\DiscordSubmitService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Log;

/**
 * Class DrawCheck
 * @package app\common\command
 */
class DrawCheck extends Command
{
    protected function configure()
    {
        $this->setName('draw_check')
            ->setDescription('校验已过3分钟的记录是否已生成');
    }

    protected function execute(Input $input, Output $output)
    {
        $nowTime = time();
        $expireTime = 3 * 60;

        $tasks = DrawTask::whereIn('status', [DrawEnum::STATUS_SUBMIT, DrawEnum::STATUS_IN_PROGRESS])
            ->whereRaw("$nowTime > create_time + $expireTime")
            ->select()->toArray();

        if (empty($tasks)) {
            echo "暂无需校验的绘画记录";
            return true;
        }

        // 处理失败次数
        $handleNum = 0;
        foreach ($tasks as $task) {
            // 查询是否已生成图但状态非成功
            $checkResult = $this->checkTask($task);
            if ($checkResult == true) {
                $handleNum += 1;
            }
        }

        echo "处理" . $handleNum . "条记录为成功";
        return true;
    }

    /**
     * @notes 查询任务
     * @param $task
     * @return bool
     * @author mjf
     * @date 2023/10/9 14:49
     */
    protected function checkTask($task)
    {
        try {
            if (empty($task['token']) || empty($task['task_id'])) {
                return false;
            }

            // 查询，图片是否已生成但监听没捕获到信息
            $detail = (new DiscordSubmitService($task['token']))->search($task['task_id']);

            // 图片地址
            $imageUrl = $detail['messages'][0][0]['attachments'][0]['url'] ?? '';
            $imageUrl = $this->imageUrlTrim($imageUrl);
            // 信息id
            $msgId = $detail['messages'][0][0]['id'] ?? '';
            $msgHash = $this->getImageHash($imageUrl);

            if (empty($imageUrl) || empty($msgId)) {
                return false;
            }

            $extension = substr($imageUrl, strrpos($imageUrl, ".") + 1);
            if (strcmp($extension, "webp") == 0) {
                return false;
            }

            DrawTask::update([
                'id' => $task['id'],
                'image_url' => $imageUrl,
                'msg_hash' => $msgHash,
                'msg_id' => $msgId,
                'finish_time' => time(),
                'status' => DrawEnum::STATUS_SUCCESS,
                'progress' => 100,
            ]);

            $notifyMsg = $this->postData($task['notify_hook'], [
                'code' => 1,
                'msg' => "成功",
                'data' => [
                    'task_id' => $task['task_id'],
                    'action' => $task['action'],
                    'image_url' => $imageUrl,
                ],
            ]);

            if ($notifyMsg != 'success') {
                Log::record("discord-check-notify-" . $task->task_id . '-' . $notifyMsg);
            }

            DrawTask::update([
                'id' => $task['id'],
                'notify_msg' => $notifyMsg . '_check',
            ]);

            return true;
        } catch (\Exception $e) {
            Log::record("discord-check-notify-" . $task['task_id'] . '-' . $e->getMessage());
            return false;
        }
    }

    /**
     * @notes post
     * @param $notifyUrl
     * @param $data
     * @return string
     * @author mjf
     * @date 2023/10/9 14:45
     */
    protected function postData($notifyUrl, $data)
    {
        $headers = [
            "Content-Type: application/json;charset=UTF-8",
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $notifyUrl);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        // 执行cURL会话
        $response = curl_exec($ch);

        // 检查请求是否成功
        if ($response === false) {
            $notifyMsg = "请求失败： " . curl_error($ch);
        } else {
            $notifyMsg = 'success';
        }

        // 关闭cURL会话
        curl_close($ch);

        return $notifyMsg;
    }

    /**
     * @notes 获取图片hash
     * @param string $imageUrl
     * @return false|string
     * @author mjf
     * @date 2023/10/9 14:45
     */
    protected function getImageHash(string $imageUrl)
    {
        $hashStartIndex = strrpos($imageUrl, "_");
        $hash = substr($imageUrl, $hashStartIndex + 1);
        return strstr($hash, ".", true);
    }

    /**
     * @notes 去除图片多余字符
     * @param $image
     * @return string
     * @author mjf
     * @date 2023/10/9 14:45
     */
    protected function imageUrlTrim($image)
    {
//        $check = strpos($image, '?ex=');
//        if ($check !== false) {
//            return mb_substr($image, 0, $check);
//        }
        return $image;
    }

}